package com.orion.config;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.orion.exception.VerfifyCodeException;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 *  验证码provider
 *
 * @author Administrator
 * @date 2021/9/13
 */
public class VerifyCodeAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        //它可是实现了authentication接口的，详看AbstractAuthenticationToken
        VerifyCodeAuthenticationToken token = (VerifyCodeAuthenticationToken) authentication;
        String inputVerifyCode = token.getVerifyCode();

        if (StringUtils.isBlank(inputVerifyCode)){
            throw new VerfifyCodeException("验证码为空");
        }

        HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Object attrObj = httpServletRequest.getSession().getAttribute("verifyCode");
        if(Objects.isNull(attrObj) || attrObj.toString().isEmpty()){
            throw new VerfifyCodeException("验证码已过期");
        }

        String sessionVerifyCode = attrObj.toString();

        if (!inputVerifyCode.equalsIgnoreCase(sessionVerifyCode)){
            throw new VerfifyCodeException("验证码不正确");
        }

        return new VerifyCodeAuthenticationToken(inputVerifyCode,authentication.getAuthorities());
    }

    /**
     * supports函数用来指明该Provider是否适用于该类型的认证，如果不合适，则寻找另一个Provider进行验证处理。
     *
     */
    @Override
    public boolean supports(Class<?> authentication) {
        //返回true后才会执行上面的authenticate方法,这步能确保authentication能正确转换类型
        return authentication.equals(VerifyCodeAuthenticationToken.class);
    }



}
